package com.nku.mason.masonframework.core.tools;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.nku.mason.masonframework.core.annotations.Action;
import com.nku.mason.masonframework.core.entities.Handler;
import com.nku.mason.masonframework.core.entities.Request;
import com.nku.mason.masonframework.util.ArrayUtil;
import com.nku.mason.masonframework.util.CollectionUtil;

/**
 * ControllerHelper :
 * 	在此处获取所有定义了Controller注解的类，可以通过反射获取该类中所有带有Action注解的方法(简称"Action方法")，获取Action注解中的请求表达式，进而获取
 * 	请求方法与请求路径，封装一个请求对象(Request)与处理对象(Handler)，最后将Request与Handler建立一个映射关系，放入一个ActionMap中，并提供一个可根据
 *  请求方法与路径获取处理对象的方法。
 *  
 * @author Mason
 * @date 2017年3月13日
 */
public final class ControllerHelper {
	/**
	 * 用于存放请求与处理器的映射关系
	 */
	private static final Map<Request, Handler> ACTION_MAP = new HashMap<Request, Handler>();
	
	static {
		//获取所有Controller类
		Set<Class<?>> controllerClassSet = ClassTool.getControllerClassSet();
		if (!CollectionUtil.isEmpty(controllerClassSet)) {
			//获取controller中所有声明的方法
			for(Class<?> controllerClass : controllerClassSet){
				Method[] methods = controllerClass.getDeclaredMethods();
				for(Method method : methods){
					//判断当前方法是否有@Action注解
					if (method.isAnnotationPresent(Action.class)) {
						Action action = method.getAnnotation(Action.class);
						//获取Action注解中注明的请求路径信息
						String mapping = action.value();
						//验证URL是否符合预先设定的规则,eg: "http方法名(get/post/put/delete):/自定义映射路径名"
						if (mapping.matches("\\w+:/\\w*")) {
							String[] strs = mapping.split(":");
							if (!ArrayUtil.isEmpty(strs) && strs.length == 2) {
								String requestMethod = strs[0];
								String requestPath = strs[1];
								//将请求方法和请求路径封装到Request对象中
								Request request = new Request(requestMethod, requestPath);
								//将当前controllerClass和请求处理方法封装至Handler中
								Handler handler = new Handler(controllerClass, method);
								//初始化ACT_MAP
								ACTION_MAP.put(request, handler);
							}					
						}		
					}
				}
			}
		}
	}
	
	/**
	 * 获取Handler 
	 * @param requetsMethod
	 * @param requestPath
	 * @return
	 */
	public static Handler getHandler(String requestMethod, String requestPath){
		Request request = new Request(requestMethod, requestPath);
		return ACTION_MAP.get(request);
	}
}






















